package com.chouren.goandroid.util;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class ImageUtil {
	/**
	 * 获取压缩后的图片
	 * 
	 * @param res
	 *            资源文件对象
	 * @param resId
	 *            资源文件id
	 * @param reqWidth
	 *            所需图片压缩尺寸最小宽度
	 * @param reqHeight
	 *            所需图片压缩尺寸最小高度
	 * @return Bitmap
	 */
	public static Bitmap decodeSampledBitmapFromResource(Resources res,
			int resId, int reqWidth, int reqHeight) {
		// 首先不加载图片,仅获取图片尺寸
		final BitmapFactory.Options options = new BitmapFactory.Options();
		// 当inJustDecodeBounds设为true时,不会加载图片仅获取图片尺寸信息
		options.inJustDecodeBounds = true;
		// 此时仅会将图片信息会保存至options对象内,decode方法不会返回bitmap对象
		BitmapFactory.decodeResource(res, resId, options);

		// 计算压缩比例,如inSampleSize=4时,图片会压缩成原图的1/4
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);

		// 当inJustDecodeBounds设为false时,BitmapFactory.decode...就会返回图片对象了
		options.inJustDecodeBounds = false;
		// 利用计算的比例值获取压缩后的图片对象
		return BitmapFactory.decodeResource(res, resId, options);
	}
	
	/**
	 * 获取压缩后的图片
	 * 			  notice: 从网络流中读取图片，并重新设置大小的过程中，因为inputstream不支持多次读取，所以使用BufferedInputStream对
	 * 					    其进行包装后以便可以多次读取，但对图片大小有限制，大小暂时设置为1024×1000；
	 * @param is
	 *            输入流
	 * @param reqWidth
	 *            所需图片压缩尺寸最小宽度
	 * @param reqHeight
	 *            所需图片压缩尺寸最小高度
	 * @return Bitmap
	 * @throws IOException 
	 */
	public static Bitmap decodeSampledBitmapFromStream(InputStream is, int reqWidth, int reqHeight) {
		
		final int bufferSize = 1024 * 1000;
		if(!is.markSupported()) {
			Logger.debug(null, "inputstream no support mark, can not redecode");
		}
		is = new BufferedInputStream(is);
		is.mark(bufferSize);
		
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeStream(is, null, options);

		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);
		options.inJustDecodeBounds = false;
		try {
			is.reset();
		} catch (IOException e) {
		}
		return BitmapFactory.decodeStream(is, null, options);
	}
	
	/**
	 * 获取压缩后的图片
	 * 
	 * @param path
	 *            图片文件
	 * @param reqWidth
	 *            所需图片压缩尺寸最小宽度
	 * @param reqHeight
	 *            所需图片压缩尺寸最小高度
	 * @return Bitmap
	 */
	public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {

		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(path, options);
		
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);
		
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(path, options);
	}
	
	/**
	 * 获取压缩后的图片
	 * 
	 * @param path
	 *            图片文件
	 * @return Bitmap
	 */
	public static Bitmap decodeSampledBitmapFromFile(String path) {
		return BitmapFactory.decodeFile(path, null);
	}

	/**
	 * 简单的计算压缩比例值
	 * 
	 * @param options
	 *            解析图片的配置信息
	 * @param reqWidth
	 *            所需图片压缩尺寸最小宽度
	 * @param reqHeight
	 *            所需图片压缩尺寸最小高度
	 * @return
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		// 保存图片原宽高值
		final int height = options.outHeight;
		final int width = options.outWidth;
		// 初始化压缩比例为1
		int inSampleSize = 1;
		
		// 当图片宽高值任何一个大于所需压缩图片宽高值时,进入循环计算
		if (height > reqHeight || width > reqWidth) {

			final int halfHeight = height / 2;
			final int halfWidth = width / 2;

			// 压缩比例值每次循环两倍增加,
			// 直到原图宽高值的一半除以压缩值后都~大于所需宽高值为止
			while ((halfHeight / inSampleSize) >= reqHeight
					&& (halfWidth / inSampleSize) >= reqWidth) {
				inSampleSize *= 2;
			}
		}

		return inSampleSize;
	}
}
